import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Container;

/**
 *	Homework 10
 * GameController Class
 *
 * This class creates creates and controlls the array of tiles for the minesweeper game.
 * I worked on the homework assignment alone, using only course materials.
 *
 *  @author Christopher Cheape
 *  @version 1.0 11/30/12
 */
 
public class GameController
{
	public Tile[][] tileList;
	private boolean firstButtonClicked;
	private Point[] bombList;
	private int x,y, mines;

	/**
	 * Contructor for the GameController. Creates the array of tiles from the supplied x and y values.
	 *
	 * @param yourX the length of the board.
	 * @param yourY the height of the board.
	 * @param yourMines the desired number of mines.
	 */
	public GameController(int yourX, int yourY, int yourMines)
	{
		x = yourX;
		y = yourY;
		mines = yourMines;
		firstButtonClicked = false;
		tileList = new Tile[x][y];
		bombList = new Point[mines];
		
		for(int i=0; i<x; i++)
		{
			for(int j=0; j<y; j++)
			{
				tileList[i][j]= new Tile(i,j,this);
				
			}
		}
		
		for(int i=0; i<mines; i++)
		{
			bombList[i] = new Point(-1,-1);
		}
	}
	
	/**
	 * Get the array of Tiles.
	 * 
	 * @return int the tile array
	 */
	public Tile[][] getTileList()
	{
		return tileList;
	}
	
	/**
	 * Gets the length of the game board.
	 * 
	 * @return int the length
	 */
	public int getLength()
	{
		return x;
	}
	
	/**
	 * Gets the height of the game board.
	 * 
	 * @return int the height
	 */
	public int getHeight()
	{
		return y;
	}
	
	/**
	 * Determines what to do when a specific JButton was clicked.
	 * If it was the first button clicked, it places the mines.
	 * If the button had a mine, it ends the game.
	 * Otherwise, it deactivates the button and states how many mines are adjacent to it.
	 * If there are none, the area is expanded.
	 *
	 * @param b the button that was clicked
	 */
	public void buttonClicked(JButton b)
	{
		if(firstButtonClicked == false)
		{
			chooseMines();
			
			for(Point p : bombList)
			{
				tileList[(int)p.getX()][(int)p.getY()].setMine(true);
			}
			
			firstButtonClicked = true;
		}

		Tile clicked = whatWasClicked(b);
		
		if(clicked.gotMine() == true)
		{
			gameOver(clicked);
		}
		
		int adjacentMines = clicked.getAdjacent();

		if(adjacentMines == 0)
		{
			expand(clicked);
		}
		
		if(adjacentMines > 0)
		{
			String label = adjacentMines+"";
			clicked.getButton().setText(label);
		}	
	}
	
	/**
	 * Chooses where to place the mines on the board.
	 */
	public void chooseMines()
	{
		Random rand = new Random();
		int bombTiles = 0;
		
		while(bombTiles < mines)
		{
			boolean ok = true;
			int potentialX = rand.nextInt(x);
			int potentialY = rand.nextInt(y);
			
			for(Point p : bombList)
			{
				if(p.getX() == potentialX && p.getY() == potentialY)
				{
				 ok = false;
				}
			}
			
			if(ok == true)
			{
				bombList[bombTiles]= new Point(potentialX,potentialY);
				bombTiles++;
			}
		}
	}
	
	/**
	 * Gets the tile that was clicked based on which JButton was clicked.
	 * 
	 * @param b the button that was clicked.
	 * @return Tile the tile that was clicked.
	 */
	public Tile whatWasClicked(JButton b)
	{
		Tile whoWasIt = new Tile(-1,-1,this);
		for(Tile[] tiles : tileList)
		{
			for(Tile tile : tiles)
			{
				if(tile.getButton() == b)
				{
					whoWasIt = tile;	
				}
			}
		}
		return whoWasIt;
	}
	
	/**
	 * Deactivates buttons based on the expansion zone found by the expandTile method in MinesweeperUtils.
	 * 
	 * @param the tile that was clicked.
	 */
	public void expand(Tile t)
	{
		ArrayList<Tile> zone = MinesweeperUtils.expandTile(t,tileList);
		
		for( Tile tile : zone)
		{
			tile.getButton().setEnabled(false);
			int adjacentMines = tile.getAdjacent();
			
			if(adjacentMines > 0)
			{
				String label = adjacentMines+"";
				tile.getButton().setText(label);
			}	
		}	
	}
	
	/**
	 * Ends the game, showing all of the bombs on the board. 
	 * It then asks the player if they would like to play again.
	 * 
	 * @param t the last tile that was clicked.
	 */
	public void gameOver(Tile t)
	{
		t.getButton().setIcon(new ImageIcon("bomb.png"));
			
			for( Point p : bombList)
			{
				tileList[(int)p.getX()][(int)p.getY()].getButton().setIcon(new ImageIcon("bomb.png"));
			}
			
			JOptionPane.showMessageDialog(null,"Sorry, you lose!");
			Starter.tryAgain(this);
	}	
	
	/**
	 * Checks to see if the player has won the game.
	 * 
	 * @param board the board that the player is trying to win.
	 */
	public void checkVictory(Tile[][] board)
	{
		int count = 0;
		for(Tile[] tiles: board)
		{
			for(Tile tile : tiles)
			{
				if(tile.getButton().isEnabled()==true)
				{
					count++;
				}
			}
		}
		if( count == mines)
		{
			JOptionPane.showMessageDialog(null,"A Winner is You!");
			Starter.tryAgain(this);
		}
	}
	
	/**
	 * Reveals the location of one of the unflagged mines when the hint button is clicked.
	 */
	public void hint()
	{
		for(Point p : bombList)
		{
			if(p.getX() != -1 && p.getY()!= -1)
			{
				if(tileList[(int)p.getX()][(int)p.getY()].gotFlag()==false)
				{
					tileList[(int)p.getX()][(int)p.getY()].getButton().setIcon(new ImageIcon("bomb.png"));
					tileList[(int)p.getX()][(int)p.getY()].setFlag(true);
					break;
				}
			}
		}
	}
	
	
	
	
	
	
	
	
	
	


}